package com.info.zhiduoduo.admin.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.Condition;
import com.info.zhiduoduo.common.constants.Constants;
import com.info.zhiduoduo.common.constants.SmartResult;
import com.info.zhiduoduo.common.constants.StatusMsg;
import com.info.zhiduoduo.common.constants.crowdsource.CrowdsourceRegfromType;
import com.info.zhiduoduo.common.constants.project.ProjectType;
import com.info.zhiduoduo.common.exception.SmartException;
import com.info.zhiduoduo.common.utils.NumberUtil;
import com.info.zhiduoduo.common.utils.StringUtil;
import com.info.zhiduoduo.core.formbean.BankCardElementFormBean;
import com.info.zhiduoduo.core.formbean.crowdsource.AddCrowdsourceModel;
import com.info.zhiduoduo.core.formbean.entrustmentproject.ImportEntrustProjectFormBean;
import com.info.zhiduoduo.core.listener.BaseAnalysisEventListener;
import com.info.zhiduoduo.core.service.CoreCrowdsourceService;
import com.info.zhiduoduo.core.service.CoreEntrustProjectServcie;
import com.info.zhiduoduo.core.service.impl.BankCardElementCertificationService;
import com.info.zhiduoduo.core.vo.entrustmentproject.ImportResultVO;
import com.info.zhiduoduo.repository.entity.company.Company;
import com.info.zhiduoduo.repository.entity.crowdsource.CrowdsourceAccount;
import com.info.zhiduoduo.repository.entity.entrustmentproject.EntrustmentProject;
import com.info.zhiduoduo.repository.entity.entrustmentproject.EntrustmentProjectItem;
import com.info.zhiduoduo.repository.entity.system.SystemProjectcategory;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 导入委托发单项目
 *
 * @author tianyonghong
 * @create 2022/8/3
 */
@Getter
@Slf4j
public class UploadEntrustProjectListener extends BaseAnalysisEventListener<ImportEntrustProjectFormBean> {

    //解析后的数据集合
    List<EntrustmentProjectItem> itemList = Lists.newArrayList();

    //企业信息
    Company company;

    //委托智众包项目 子项目自然人绑定的企业集合 key：企业名称，value：企业ID
    Map<String, Integer> itemBindCompanyMap = new HashMap<>();

    //是否银行卡校验(0/1:否、2要素校验、3要素校验、4要素校验)
    Integer isCheckBankCard;
    EntrustmentProject entrustmentProject;
    CoreCrowdsourceService coreCrowdsourceService;
    CoreEntrustProjectServcie coreEntrustProjectServcie;

    public UploadEntrustProjectListener(EntrustmentProject entrustmentProject, Integer isCheckBankCard,
                                        CoreCrowdsourceService coreCrowdsourceService,
                                        CoreEntrustProjectServcie coreEntrustProjectServcie) {
        this.isCheckBankCard = isCheckBankCard;
        this.entrustmentProject = entrustmentProject;
        this.coreCrowdsourceService = coreCrowdsourceService;
        this.coreEntrustProjectServcie = coreEntrustProjectServcie;
    }

    @Override
    public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
        int index = context.readRowHolder().getRowIndex() + 1;
        //设置企业名称
        if (index == 4) {
            //返回名字
            if (headMap.size() < 2 && StringUtils.isBlank(headMap.get(1).getStringValue())) {
                throw new ExcelAnalysisException("受票方公司名称不能为空");
            }
            String compname = headMap.get(1).getStringValue();
            List<Company> companyList = new Company().selectList(Condition.create().eq("compname", compname));
            if (CollectionUtils.isEmpty(companyList)) {
                throw new SmartException(StatusMsg.StatusMsg_302);
            }
            if (companyList.size() > 1) {
                throw new SmartException(StatusMsg.StatusMsg_346);
            }
            company = companyList.get(0);
            // 企业必须开启了智众包功能,才能发智众包项目
            if (ProjectType.isCrowdsourceProject(entrustmentProject.getProjectType()) && !NumberUtil.equals(company.getIntelCrowdsource(), 2)) {
                throw new SmartException(StatusMsg.StatusMsg_352);
            }
            entrustmentProject.setCompid(company.getCompid());
            entrustmentProject.setCompname(company.getCompname());
        }
        if (index == 6) {
            Integer headIndex = 11;
            if(headMap != null && headMap.get(headIndex) != null){
                //收款方账户(支付宝账号)
                if(!StringUtils.contains(headMap.get(headIndex).getStringValue(),"支付宝账号")){
                    throw new SmartException(StatusMsg.StatusMsg_339);
                }
            }
        }
    }

    @Override
    public void invoke(ImportEntrustProjectFormBean formBean, AnalysisContext analysisContext) {
        super.invoke(formBean, analysisContext);

        // 单条数据校验
        boolean result = checkValidExcelData(formBean, index);
        if (result) {
            EntrustmentProjectItem item = new EntrustmentProjectItem();
            BeanUtils.copyProperties(formBean, item);
            item.setIndex(Integer.parseInt(formBean.getIndex()))
                .setProjectAmount(formBean.getProjectAmount())
                .setCrowdsourceName(formBean.getPayeeName())
                .setProjectType(entrustmentProject.getProjectType())
                .setCompid(company.getCompid())
                .setCompname(company.getCompname())
                .setPrincipalId(entrustmentProject.getPrincipalId());

            // 设置服务费税费
            coreEntrustProjectServcie.calculateItemAmount(item, company, entrustmentProject.getImportedServiceRate(), entrustmentProject.getProjectType());
            itemList.add(item);
        }
    }

    /**
     * 数据校验
     *
     * @param formBean
     * @param index
     * @return
     */
    private boolean checkValidExcelData(ImportEntrustProjectFormBean formBean, int index) {

        //项目分类
        if (StringUtil.isNotEmpty(formBean.getCategory())) {
            SystemProjectcategory category = new SystemProjectcategory().selectOne(Condition.create()
                                                                                            .eq("projectcategory", formBean.getCategory())
                                                                                            .last(" limit 1 "));
            if (null != category) {
                formBean.setCategoryid(category.getProjectcategoryid());
            }
        }
        //银行卡/支付宝账户非空校验 支付宝：accountType=1;银行卡:accountType=2:
        if(formBean.getAccountType() == 1 && StringUtils.isBlank(formBean.getAlipayLogonId())){
            errorPrompt.add("请检查第[" + index + "]行数据：收款方支付宝帐号不能为空");
            return false;
        }
        if(formBean.getAccountType() == 2 && StringUtils.isBlank(formBean.getBankNo())){
            errorPrompt.add("请检查第[" + index + "]行数据：收款方银行卡号不能为空");
            return false;
        }
        // 设置回显 AccountNo
        if(formBean.getAccountType() == 1){
            formBean.setAccountNo(formBean.getAlipayLogonId());
        }
        if(formBean.getAccountType() == 2){
            formBean.setAccountNo(formBean.getBankNo());
        }

        //查询自然人
        CrowdsourceAccount crowdsource = handleCrowdSourceAccount(formBean);
        formBean.setCrowdsourceid(crowdsource.getCrowdsourceid());

        //银行卡要素认证 二要素姓名和银行卡必传，三要素姓名+银行卡+身份证号
        if (isCheckBankCard != null && crowdsource.getIsCheckBankCard() != 1
                && formBean.getAccountType() == 2 && !NumberUtil.intIn(isCheckBankCard, 0, 1)) {
            BankCardElementFormBean bankCardElementFormBean = null;
            if (isCheckBankCard == 2) {
                bankCardElementFormBean = BankCardElementFormBean.ofTwo(formBean.getPayeeName(), formBean.getBankNo());
            } else if (isCheckBankCard == 3) {
                bankCardElementFormBean = BankCardElementFormBean.ofThree(formBean.getPayeeName(), formBean.getBankNo(), formBean.getPayeeIdNo());
            } else if (isCheckBankCard == 4) {
                bankCardElementFormBean = BankCardElementFormBean.ofAll(formBean.getPayeeName(), formBean.getBankNo(), formBean.getPayeeIdNo(), formBean.getPhone());
            }
            if (bankCardElementFormBean != null) {
                Integer bankResult = BankCardElementCertificationService.getBankCardElement(bankCardElementFormBean);
                //1核验一致; 2核验不一致; 3无效卡号或卡状态异常，请换卡重试或联系发卡行;
                if (bankResult == null) {
                    errorPrompt.add("请检查第[" + index + "]行数据：银行卡核验出错");
                    return false;
                } else if (bankResult == 2) {
                    errorPrompt.add("请检查第[" + index + "]行数据：银行卡核验不一致");
                    return false;
                } else if (bankResult == 3) {
                    errorPrompt.add("请检查第[" + index + "]行数据：无效卡号或卡状态异常，请换卡重试或联系发卡行");
                    return false;
                } else if(bankResult == 1){
                    crowdsource.setIsCheckBankCard(1).updateById();
                }
            }
        }

        return true;
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 有失败的数据，则返回
        if (CollectionUtils.isNotEmpty(errorPrompt)) {
            smartResult = SmartResult.fail(StatusMsg.StatusMsg_1109, errorPrompt);
            return;
        }

        //新增主项目
        entrustmentProject.insert();
        //批量新增
        for (EntrustmentProjectItem item : itemList) {
            item.setImportId(entrustmentProject.getId());
            item.insert();
        }
        // 更新大项目
        coreEntrustProjectServcie.calcProjectTotalAmount(entrustmentProject, itemList);
        entrustmentProject.setTotalItemCount(itemList.size())
                          .setImportedItemCount(itemList.size())
                          .setImportedServiceRate(itemList.get(0).getServiceRate())
                          .setImportedItemJson(JSON.toJSONString(itemList))
                          .updateById();

        ImportResultVO vo = new ImportResultVO();
        vo.setImportId(entrustmentProject.getId());
        vo.setImportList(itemList);
        smartResult = SmartResult.success(vo);
    }

    /**
     * 处理自然人逻辑 根据身份证+姓名查找自然人 1：查询成功，覆盖银行卡或者支付 2:查询失败，新增自然人
     * @param bean
     * @return crowdsourceid  返回自然人ID
     */
    private CrowdsourceAccount handleCrowdSourceAccount(ImportEntrustProjectFormBean bean) {
        CrowdsourceAccount crowdsourceAccount = new CrowdsourceAccount().selectOne(Condition.create()
                                                                                            .eq("idno", bean.getPayeeIdNo())
                                                                                            .eq("realname", bean.getPayeeName())
                                                                                            .last(" limit 1 "));

        // 智众包项目 自然人绑定的企业, 优先看导入的子项目上的Bindcompname, 没有则用受票方企业id
        Integer bindcompid = company.getCompid();
        if (StringUtils.isNotBlank(bean.getBindcompname())) {
            bindcompid = itemBindCompanyMap.computeIfAbsent(bean.getBindcompname(), k -> {
                Company itemBindComp = new Company().selectOne(Condition.create()
                                                                        .eq("compname", bean.getBindcompname())
                                                                        .eq("state", Constants.comp_state_4)
                                                                        .last(" limit 1 "));
                return itemBindComp != null ? itemBindComp.getCompid() : company.getCompid();
            });
        }
        bean.setBindcompid(bindcompid);

        if (crowdsourceAccount == null) {
            AddCrowdsourceModel model = new AddCrowdsourceModel().setIdno(bean.getPayeeIdNo())
                                                                 .setPhone(bean.getPhone())
                                                                 .setRealname(bean.getPayeeName())
                                                                 .setRegfrom(CrowdsourceRegfromType.ENTRUSTMENT_PROJECT)
                                                                 .setBindcompid(bindcompid);

            if (StringUtils.isNotBlank(bean.getBankNo())) {
                model.setAcctno(bean.getBankNo());
            }
            if (StringUtils.isNotBlank(bean.getAlipayLogonId())) {
                model.setAlipayLogonId(bean.getAlipayLogonId());
            }
            return coreCrowdsourceService.addCrowdsourceAccount(model);
        } else {
            // 更新支付宝账号
            if (StringUtils.isNotBlank(bean.getAlipayLogonId())) {
                crowdsourceAccount.setAlipayLogonId(bean.getAlipayLogonId()).updateById();
            }
            // 更新银行卡号
            if (StringUtils.isNotBlank(bean.getBankNo()) &&
                    !StringUtils.equals(bean.getBankNo(),crowdsourceAccount.getAcctno()) ) {
                crowdsourceAccount.setAcctno(bean.getBankNo()).setIsCheckBankCard(0).updateById();
            }
        }
        return crowdsourceAccount;
    }
}
